package com.droidnova.android.games.vortex;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.StringTokenizer;

import android.app.Application;
import android.content.Context;
import android.os.Environment;
import android.util.Log;

public class export extends Application {
	
	public static final String LOG_TAG = "Droidnova";

	int _noVertices = 0;
	float _intensity[]=null ,_intensity1[]=null;
	private String _new[]=null,_even[]=null,_odd[]=null, _points[]=null ,_points1[],_new1[]=null;
	float max_value=0.0f,min_value=0.0f ,range=0.0f,range1=0.0f;
	float cr = 0.9f,cg=0.3f ,ca=1.0f;
	int number=0;
	float _pcolors[]=null , _pvertices[]=null , _pvertices1[]=null ;
	//byte[] _pindicesnew = null;
	//int[] _pindicesnew = null;
	short[] _pindicesnew = null;
	float incy =0.0f, incx=0.0f,incz=0.0f;
	//calculate color values for each point
	int count=0;
	float i_value=0.0f,cb = 0.0f;
	ArrayList <String> points1 = new ArrayList<String>();
	int l1=0,l2=0,l3=0,l2c=0; 
	

	public export(Context ctx,String filename)
	{
		Log.w("MyClassName", "points");
		if(filename==null)
		{
		createVC(null);
		}
		else
		{
		createVC(filename);	
		}
		

	}
	
	public void createVC(String fname)
	{
		_noVertices = 0;
		_intensity=null ;
		_new=null;
		_even=null;
		_odd=null;
		_points=null;
		max_value=0.0f;
		cr = 0.9f;
		cg=0.3f;
		ca=1.0f;
		number=0;
		_pcolors=null;
		_pvertices=null; 
		_pindicesnew =null;
		//calculate color values for each point
		count=0;
		i_value=0.0f;
		cb = 0.0f;
		incy =0.0f;
		incx=0.0f;
		incz=0.0f;
		l1=0;
		l2=0;
		l3=0;
		//Step 2 -Load file
		
		
		
		File sdcard1 = Environment.getExternalStorageDirectory();
		File file1 = null;
		if(fname==null)
		{
			file1 = new File(sdcard1,"inputi1.txt");
			//file1 = new File(sdcard1,"slowness_lsqr_16_high_allray.txt");
		}
		else
		{
		file1 = new File(sdcard1,fname);
		}
		//File file1 = new File(sdcard1,"inputi1.txt");
		BufferedReader br1 = null;
		String stringRead1 = null;
		ArrayList <String> intensity1 = new ArrayList<String> ();
		
		       //buffered reader
			try {
				br1 = new BufferedReader(new FileReader(file1));
				} 
			catch (FileNotFoundException e1) 
				{
				// TODO Auto-generated catch block
				e1.printStackTrace();
				}
			   //read first line
			try {
				l1 = Integer.parseInt(br1.readLine( ));
				l2 =Integer.parseInt(br1.readLine( ));
				l2c=l2;
				l3 =Integer.parseInt(br1.readLine( ));
				Log.v("l values", "***l values-> l1=" + l1+"l2="+ l2+"l3="+ l3);
				stringRead1 = br1.readLine( );
				} 
			catch (IOException e) 
				{
				e.printStackTrace();
				}
			
			while( stringRead1 != null ) // end of the file?
			{	

				intensity1.add(stringRead1);
		       //read nextline
				try {
					stringRead1 = br1.readLine( );
					} 
				catch (IOException e) {
					e.printStackTrace();
					}
			}
			//convert to string array
			_new1 = intensity1.toArray(new String[intensity1.size()]);
			
			
			//convert to float array
			try {
				_intensity1 = convertStringArraytoFloatArray(_new1);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			Log.v("***_intensity1", "***_intensity1 total elements -> ***" + _intensity1.length);
			for(int s=0;s<_intensity1.length;s++)
			{
				_intensity1[s]=(Math.round(_intensity1[s]*10000.0f))/10000.0f;
				//Log.v("***_intensity1", "***_intensity1 -> ***" + _intensity1[s]);
			}
				
			//3rd step
			int p=0,q=0,r=0,rem=0,rem1=0;
			//ArrayList <String> intensity2 = new ArrayList<String> ();
			ArrayList<Float> intensity2 = new ArrayList<Float>();
			for(int s=1;s<=_intensity1.length;s++)
			{
				rem=s%(l2*l3); // remainder1
				p = (s-rem)/(l2*l3); //quotient1
				rem1 = s%l3;    //remainder2
				q = (s-rem1)/l3;  //quotient2
				r = s % l3;
				//condition
				if( (s>(l2*l3)) && ((p%l2)==0) && ((q%l3)==0) && (r==0))
				{
					intensity2.add(_intensity1[(s-1)]);
		   		    intensity2.add(_intensity1[(s-1)]);
					p=l1-1;
					for(q=0;q<=l2;q++)
					{
						if (q==l2) l2=l2-1;
						for(r=0;r<=l3;r++)
						{
							intensity2.add(_intensity1[(p*(l3*l2)+(q*l3))+(r-1)]);
							if (r==l3) intensity2.add(_intensity1[(p*(l3*l2)+(q*l3))+(r-1)]);
						}
					}
				}
				else if((s>(l3)) && (q%l3==0) && (r==0))
				{
					intensity2.add(_intensity1[(s-1)]);
		   		    intensity2.add(_intensity1[(s-1)]);
					q=l2-1;
					for(r=0;r<=l3;r++)
					{
						intensity2.add(_intensity1[(p*(l3*l2)+(q*l3))+(r-1)]);
					}
				}
				else
				{
					intensity2.add(_intensity1[(s-1)]);
					if(r==0 && s>0)
					{
					 r=l3;
					 intensity2.add(_intensity1[(s-1)]);
					}
				}
			}
			l2=l2c;
			Log.v("***_intensity2", "***_intensity2 total elements -> ***" + intensity2.size());
			
			//convert to float array
			_intensity = toPrimitiveArray(intensity2);
			
			
			//end of 3rd step
		//end of new method 
		
			// new method
			_pvertices1=null;
			_pvertices=null;
			points1.clear();
			
			
			incx =(Math.round((1/(float)l1)*10000.0f))/10000.0f;
			incy =(Math.round((1/(float)l2)*10000.0f))/10000.0f;
			incz =(Math.round((1/(float)l3)*10000.0f))/10000.0f;
			Log.v("***values", "***values***" + " l1= "+l1 + " l2= "+l2+" l3= "+l3+" incx= "+incx+" incy= "+incy+" incz= "+incz);
			int counter=0;
			float x=0.0f , y=0.0f, z =0.0f;
			for(x=0.0f;x<=1.0f;x+=incx)
			{
				x=(Math.round(x*10000.0f))/10000.0f; 
				for(y=0.0f;y<=1.0f;y+=incy)
				{
					y=(Math.round(y*10000.0f))/10000.0f; 
					for(z=0.0f;z<=1.0f;z+=incz)
					{
						counter++;
						z=(Math.round(z*10000.0f))/10000.0f; 
						points1.add(String.valueOf(x));
						points1.add(String.valueOf(y));
						points1.add(String.valueOf(z));
					}
				}
			}
			_points1 = points1.toArray(new String[points1.size()]);
			try {
				_pvertices1 = convertStringArraytoFloatArray(_points1);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
				_pvertices = _pvertices1;
				for(int i=0;i<_pvertices.length;i++)
				{
					_pvertices[i]= _pvertices[i]-0.5f;
					_pvertices[i]=(Math.round(_pvertices[i]*10000.0f))/10000.0f; 
				}
		
			//indices
			//ArrayList<Byte> pindices = new ArrayList<Byte>();
				ArrayList<Short> pindices = new ArrayList<Short>();
				int p1,p2,p3,p4,p5,p6,p7,p8;
			for(int i=0 ;i<(_intensity.length-((l2+1)*(l3+1)));i++)
			{	
				
			if ( ((i % (l3+1)) < l3 ) && (i% ((l3+1)*(l2+1)) < ((l3+1)*l2)) )
			//if ( ((i % (l3+1)) < l3 ) )
             {
              // int p1 = i;
              // int p2 = i + (l3 + 1);
             //  int p3 = i + (l3 + 2);
              // int p4 = i + 1;
            
               /*pindices.add(Short.valueOf(String.valueOf(p1)));
               pindices.add(Short.valueOf(String.valueOf(p2)));
               pindices.add(Short.valueOf(String.valueOf(p3)));
               pindices.add(Short.valueOf(String.valueOf(p1)));
               pindices.add(Short.valueOf(String.valueOf(p3)));
               pindices.add(Short.valueOf(String.valueOf(p4)));*/
            
               
               //new algo
               p1 =i;
               p2 = i+(l3+1);
               p3= i+((l2+1)*(l3+1)+(l3+1));
               p4 = i+((l2+1)*(l3+1));
               p5 = i+1;
               p6 = i+((l3+1)+1);
               p7 = p3+1;
               p8 = p4+1;
               
               pindices.add((short)p1);
               pindices.add((short)p2);
               pindices.add((short)p4);
               pindices.add((short)p2);
               pindices.add((short)p3);
               pindices.add((short)p4);
               
               pindices.add((short)p1);
               pindices.add((short)p2);
               pindices.add((short)p5);
               pindices.add((short)p2);
               pindices.add((short)p5);
               pindices.add((short)p6);
               
               pindices.add((short)p1);
               pindices.add((short)p4);
               pindices.add((short)p5);
               pindices.add((short)p4);
               pindices.add((short)p5);
               pindices.add((short)p8);
               
               pindices.add((short)p2);
               pindices.add((short)p3);
               pindices.add((short)p6);
               pindices.add((short)p3);
               pindices.add((short)p6);
               pindices.add((short)p7);
               
               
               pindices.add((short)p3);
               pindices.add((short)p4);
               pindices.add((short)p8);
               pindices.add((short)p3);
               pindices.add((short)p7);
               pindices.add((short)p8);
               
               pindices.add((short)p5);
               pindices.add((short)p6);
               pindices.add((short)p8);
               pindices.add((short)p6);
               pindices.add((short)p7);
               pindices.add((short)p8);
              /* pindices.add(Short.valueOf(String.valueOf(p2)));
               pindices.add(Short.valueOf(String.valueOf(p4)));
               pindices.add(Short.valueOf(String.valueOf(p2)));
               pindices.add(Short.valueOf(String.valueOf(p3)));
               pindices.add(Short.valueOf(String.valueOf(p4)));
               
               pindices.add(Short.valueOf(String.valueOf(p1)));
               pindices.add(Short.valueOf(String.valueOf(p2)));
               pindices.add(Short.valueOf(String.valueOf(p5)));
               pindices.add(Short.valueOf(String.valueOf(p2)));
               pindices.add(Short.valueOf(String.valueOf(p5)));
               pindices.add(Short.valueOf(String.valueOf(p6)));
               
               pindices.add(Short.valueOf(String.valueOf(p1)));
               pindices.add(Short.valueOf(String.valueOf(p4)));
               pindices.add(Short.valueOf(String.valueOf(p5)));
               pindices.add(Short.valueOf(String.valueOf(p4)));
               pindices.add(Short.valueOf(String.valueOf(p5)));
               pindices.add(Short.valueOf(String.valueOf(p8)));
               
               pindices.add(Short.valueOf(String.valueOf(p2)));
               pindices.add(Short.valueOf(String.valueOf(p3)));
               pindices.add(Short.valueOf(String.valueOf(p6)));
               pindices.add(Short.valueOf(String.valueOf(p3)));
               pindices.add(Short.valueOf(String.valueOf(p6)));
               pindices.add(Short.valueOf(String.valueOf(p7)));
               
               
               pindices.add(Short.valueOf(String.valueOf(p3)));
               pindices.add(Short.valueOf(String.valueOf(p4)));
               pindices.add(Short.valueOf(String.valueOf(p8)));
               pindices.add(Short.valueOf(String.valueOf(p3)));
               pindices.add(Short.valueOf(String.valueOf(p7)));
               pindices.add(Short.valueOf(String.valueOf(p8)));
               
               pindices.add(Short.valueOf(String.valueOf(p5)));
               pindices.add(Short.valueOf(String.valueOf(p6)));
               pindices.add(Short.valueOf(String.valueOf(p8)));
               pindices.add(Short.valueOf(String.valueOf(p6)));
               pindices.add(Short.valueOf(String.valueOf(p7)));
               pindices.add(Short.valueOf(String.valueOf(p8)));*/
             }
			}
			
			_pindicesnew = toPrimitiveShortArray(pindices);
            /* for(int i=0;i<pindices.size();i++)
             {
            	 Log.v("pindices","pindices"+pindices.get(i));
             }*/
             
           //end of indices
			
			
		_noVertices = _intensity.length ;  //DOUBT
		 number = _intensity.length *4;
         
		Log.v("NUMBER", "FOUND NUMBER -> " + number);
		_pcolors = new float[number];
		max_value = getMaxValue(_intensity);
		min_value = getMinValue(_intensity);
		range = max_value - min_value;
		range1 = range/4;
		for(int i = 0;i<_intensity.length;i++)
		{		
			i_value = _intensity[i];
			cb = i_value;
			
			//color of values
			
			if( cb >= min_value+(0*range1)   && cb <= min_value+(1*range1))
			{
				cr = 1.0f;
				cg=0.8f;
				cb=0.6f;	
			}
			else if( cb > min_value+(1*range1) && cb <= min_value+(2*range1))
			{
				cr=0.0f;
				cg=0.0f;
				cb=1.0f;
			}
			else if(cb > min_value+(2*range1)  && cb <= min_value+(3*range1))
			{
				cr = 0.0f;
				cg = 1.0f;
				cb = 0.0f;
			}
			else if(cb > min_value+(3*range1) && cb <= max_value)
			{
			
				cr = 1.0f;
				cg = 0.0f;
				cb = 0.0f;
			}
			
			for(int j=0;j<=3;j++)
			{
				if(j==0)
				{
					_pcolors[count]=cr;	
				}
				else if(j==1)
				{
					_pcolors[count]=cg;	
				}
				else if(j==2)
				{
					_pcolors[count]=cb;
				}
				else
				{
					_pcolors[count]=ca;	
				}
				count++;
			}
			
			
		}
	}
	
	//conversion ofstring array to float array	
	public float[] convertStringArraytoFloatArray(String[] _new) throws Exception 
	{
		if (_new != null)
		{
			float floatarray[] = new float[_new.length];
			for (int i = 0; i < _new.length; i++) {
				floatarray[i] = Float.parseFloat(_new[i]);
			}
			return floatarray;
		}
		return null;
	}
	// Finding the maximum value in an array
	public float getMaxValue(float[] numbers){  
		float maxValue = numbers[0];  
		for(int i=1;i < numbers.length;i++){  
			if(numbers[i] > maxValue){  
				maxValue = numbers[i];
			}  
		}  
		return maxValue;  
	}  
	
	public float getMinValue(float[] numbers){  
		float minValue = numbers[0];  
		for(int i=1;i < numbers.length;i++){  
			if(numbers[i] < minValue){  
				minValue = numbers[i];
			}  
		}  
		return minValue;  
	}  
	
	public float getMinXValue(float[] numbers){  
		float minValue = numbers[0];  
		for(int i=3;i < numbers.length;i+=3){  
			if(numbers[i] < minValue){  
				minValue = numbers[i];
			}  
		}  
		return minValue;  
	}
	
	public float getMinYValue(float[] numbers){  
		float minValue = numbers[1];  
		for(int i=4;i < numbers.length;i+=3){  
			if(numbers[i] < minValue){  
				minValue = numbers[i];
			}  
		}  
		return minValue;  
	} 
	
	public float getMinZValue(float[] numbers){  
		float minValue = numbers[2];  
		for(int i=5;i < numbers.length;i+=3){  
			if(numbers[i] < minValue){  
				minValue = numbers[i];
			}  
		}  
		return minValue;  
	}
	
	// Finding the maximum x value in an array
	public float getMaxXValue(float[] numbers){  
		float maxValue = numbers[0];  
		for(int i=3;i < numbers.length;i+=3){  
			if(numbers[i] > maxValue){  
				maxValue = numbers[i];
			}  
		}  
		return maxValue;  
	}  
	
	// Finding the maximum Y value in an array
	public float getMaxYValue(float[] numbers){  
		float maxValue = numbers[1];  
		for(int i=4;i < numbers.length;i+=3){  
			if(numbers[i] > maxValue){  
				maxValue = numbers[i];
			}  
		}  
		return maxValue;  
	}  
	
	// Finding the maximum Z value in an array
	public float getMaxZValue(float[] numbers){  
		float maxValue = numbers[2];  
		for(int i=5;i < numbers.length;i+=3){  
			if(numbers[i] > maxValue){  
				maxValue = numbers[i];
			}  
		}  
		return maxValue;  
	} 
	//Convertion from a object to premitive array
	private float[] toPrimitiveArray(final ArrayList<Float> vertexList) {
	    final float[] primitives = new float[vertexList.size()];
	    int index = 0;
	    for (Float object : vertexList) {
	        primitives[index++] = object;
	    }
	    return primitives;
	}
	 private byte[] toPrimitiveByteArray(final ArrayList<Byte> vertexList)
	  {
	    final byte[] primitives = new byte[vertexList.size()];
	    int index = 0;
	    for (Byte object : vertexList) {
	        primitives[index++] = object;
	    }
	    return primitives;
	    }
	 private short[] toPrimitiveShortArray(final ArrayList<Short> vertexList)
	  {
	    final short[] primitives = new short[vertexList.size()];
	    int index = 0;
	    for (Short object : vertexList) {
	        primitives[index++] = object;
	    }
	    return primitives;
	    }

	 private int[] toPrimitiveInt(final ArrayList<Integer> vertexList) {
		    final int[] primitives = new int[vertexList.size()];
		    int index = 0;
		    for (Integer object : vertexList) {
		        primitives[index++] = object;
		    }
		    return primitives;
		}
}
